package cn.jofei.common.netty.handler;

import cn.jofei.common.monitor.msg.DingMsg;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.util.ReferenceCountUtil;

/**
 * 直接转发处理器
 *
 * @author Jofei Bao
 * @version ngbao v2.0
 * @date 2022年10月17日 23:03
 */
public class RelayHandler extends ChannelInboundHandlerAdapter {

    private final Channel remoteChannel;

    public RelayHandler(Channel remoteChannel) {
        this.remoteChannel = remoteChannel;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        remoteChannel.writeAndFlush(msg);
        if (msg instanceof DefaultHttpResponse){
            ReferenceCountUtil.safeRelease(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        DingMsg.markdown("Ngbao监控").text(String.format("#### Ngbao监控\n#### 数据转发异常\n##### 原因：%s", cause.getMessage())).build().send();
        flushAndClose(ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        /**
         * 连接断开时关闭另一端连接。
         * 如果代理到远端服务器连接断了也同时关闭代理到客户的连接。
         * 如果代理到客户端的连接断了也同时关闭代理到远端服务器的连接。
         */
        flushAndClose(remoteChannel);
    }

    private void flushAndClose(Channel ch) {
        if (ch != null && ch.isActive()) {
//            ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
            ch.close();
        }
    }
}